import { profileList, profileAdd, profileEdit } from '@/services/profile'
import Criteria from '@/utils/criteria'
import { OPERATOR } from '@/store/mutation-types'
class UserProfile {
  constructor() {
    this.profileMap = new Map() // 后台存储的配置
    this.profileAjax = new Map() // 正在请求的方法
    this.profileAwaitAjax = new Map() // 正在等待请求的方法
  }
  setProfile(data) { // 前台按用户、页面、组件暂存数据
    data.forEach(item => {
      this.profileMap.set(`${item.userId}:${item.pageKey}:${item.elementKey}`, item)
    })
  }
  async getProfile(data) { // 获取用户页面组件配置
    const key = `${data.userId}:${data.pageKey}:${data.elementKey}`
    if (this.profileMap.get(key)) { // 先获取缓存，若已存在，直接返回
      return this.profileMap.get(key)
    }
    const res = await this.getProfileByPage(data) // 未获取到缓存，按页面请求用户配置数据
    const profileData = res.filter(item => {
      return item.elementKey === data.elementKey
    })
    return profileData[0] || {}
  }
  getProfileByPage(data) { // 请求后台用户配置
    return new Promise((resolve, reject) => {
      const key = `${data.userId}:${data.pageKey}`
      if (this.profileAjax.get(key)) { // 页面请求已发送。不再继续请求,避免重复请求
        const awaitAjax = this.profileAwaitAjax.get(key) || []
        awaitAjax.push((res) => { // 暂存重复的请求方法
          if (res.code === 200) {
            resolve(res.result)
          } else {
            reject(res)
          }
        })
        this.profileAwaitAjax.set(key, awaitAjax)
      } else { // 按页面请求数据
        const param = this.getProfileParams({
          userId: data.userId,
          pageKey: data.pageKey
        })
        const ajax = profileList(param).then(res => {
          if (res.code === 200) {
            this.setProfile(res.result)
          }
          resolve(res.result)
          // 回调暂存的请求方法
          this.profileAwaitAjax.get(key)?.forEach((fn) => {
            fn(res)
          })
          // 清空页面请求map
          this.profileAjax.delete(key)
          this.profileAwaitAjax.delete(key)
        }).catch((err) => {
          reject(err)
        })
        this.profileAjax.set(key, ajax) // 前端缓存正在请求的方法
      }
    })
  }
  async saveProfile(data) { // 保存用户配置
    try {
      let res
      const key = `${data.userId}:${data.pageKey}:${data.elementKey}`
      // 若用户未先获取数据，先调用保存接口，会重复产生配置数据，实际使用需要避免
      if (this.profileMap.get(key)) { // 判断是否已存在，若存在调用编辑接。目前这个地方会有bug
        res = await profileEdit([{
          ...data,
          id: this.profileMap.get(key).id
        }])
      } else { // 调用新增接口
        res = await profileAdd([data])
      }
      if (res.code === 200) {
        this.setProfile(res.result)
      }
    } catch (error) {
      console.log(error)
    }
  }
  getProfileParams(data) { // 获取查询条件
    const queryParam = new Criteria()
    queryParam.addCriterions(Object.assign({}, data), OPERATOR.EQ)// 过滤参数转换为jpa支持格式
    var param = Object.assign({}, { criteria: queryParam.getEncode() })
    return param
  }
}

const profile = new UserProfile()

export default profile
